using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

using SLProxy;
using libsecondlife;
using libsecondlife.Packets;
using System.Net;

namespace StickyChat
{
    public class StickyFriends : UserControl, StickIn
    {
        const int AVATAR_ONLINE = 0x1 << 4; // the online status of this avatar, if known.

        private StickyServices loader;
        private Button fix;
        private string myName;
        private Button allon;
        private Button dump;
        private TextBox friendsDump;
        private Button alloff;
        //private Hashtable friends;

        public StickyFriends(StickyServices p)
        {
            loader = p;
            myName = "Friends";
            InitializeComponent();
        }

        private void InitializeComponent()
        {
            this.fix = new System.Windows.Forms.Button();
            this.allon = new System.Windows.Forms.Button();
            this.alloff = new System.Windows.Forms.Button();
            this.dump = new System.Windows.Forms.Button();
            this.friendsDump = new System.Windows.Forms.TextBox();
            this.SuspendLayout();
            // 
            // fix
            // 
            this.fix.Location = new System.Drawing.Point(51, 32);
            this.fix.Name = "fix";
            this.fix.Size = new System.Drawing.Size(75, 23);
            this.fix.TabIndex = 0;
            this.fix.Text = "FIXXORZ";
            this.fix.UseVisualStyleBackColor = true;
            this.fix.Click += new System.EventHandler(this.fix_Click);
            // 
            // allon
            // 
            this.allon.Location = new System.Drawing.Point(51, 3);
            this.allon.Name = "allon";
            this.allon.Size = new System.Drawing.Size(75, 23);
            this.allon.TabIndex = 1;
            this.allon.Text = "All Online";
            this.allon.UseVisualStyleBackColor = true;
            this.allon.Click += new System.EventHandler(this.allon_Click);
            // 
            // alloff
            // 
            this.alloff.Location = new System.Drawing.Point(132, 3);
            this.alloff.Name = "alloff";
            this.alloff.Size = new System.Drawing.Size(75, 23);
            this.alloff.TabIndex = 2;
            this.alloff.Text = "All Offline";
            this.alloff.UseVisualStyleBackColor = true;
            this.alloff.Click += new System.EventHandler(this.alloff_Click);
            // 
            // dump
            // 
            this.dump.Location = new System.Drawing.Point(132, 32);
            this.dump.Name = "dump";
            this.dump.Size = new System.Drawing.Size(75, 23);
            this.dump.TabIndex = 3;
            this.dump.Text = "Dump Keys";
            this.dump.UseVisualStyleBackColor = true;
            this.dump.Click += new System.EventHandler(this.dump_Click);
            // 
            // friendsDump
            // 
            this.friendsDump.Location = new System.Drawing.Point(3, 61);
            this.friendsDump.Multiline = true;
            this.friendsDump.Name = "friendsDump";
            this.friendsDump.ScrollBars = System.Windows.Forms.ScrollBars.Both;
            this.friendsDump.Size = new System.Drawing.Size(244, 163);
            this.friendsDump.TabIndex = 4;
            this.friendsDump.Text = "Hit Dump Keys to dump a list of your friends and their keys here, in a format sim" +
                "ilar to name.cache";
            this.friendsDump.WordWrap = false;
            // 
            // StickyFriends
            // 
            this.Controls.Add(this.friendsDump);
            this.Controls.Add(this.dump);
            this.Controls.Add(this.alloff);
            this.Controls.Add(this.allon);
            this.Controls.Add(this.fix);
            this.Name = "StickyFriends";
            this.Size = new System.Drawing.Size(258, 238);
            this.ResumeLayout(false);
            this.PerformLayout();

        }

        #region StickIn Members

        public string name
        {
            get { return myName; }
        }

        public void start()
        {
            //loader.proxy.AddDelegate(PacketType.DirPeopleReply, Direction.Incoming, DirPeopleReply);
            //loader.proxy.AddDelegate(PacketType.UUIDNameReply, Direction.Incoming, UUIDNameReply);
            loader.proxy.AddDelegate(PacketType.AvatarPropertiesReply, Direction.Incoming, AvatarPropertiesReply);
        }

        public void stop()
        {
            //loader.proxy.RemoveDelegate(PacketType.DirPeopleReply, Direction.Incoming, DirPeopleReply);
            //loader.proxy.RemoveDelegate(PacketType.UUIDNameReply, Direction.Incoming, UUIDNameReply);
            loader.proxy.RemoveDelegate(PacketType.AvatarPropertiesReply, Direction.Incoming, AvatarPropertiesReply);
        }
        #endregion StickIn Members
/*
        private Packet DirPeopleReply(Packet packet, IPEndPoint sim)
        {
            // deconstruct the packet
            DirPeopleReplyPacket people = (DirPeopleReplyPacket)packet;
            Console.WriteLine("Received DirPeopleReply packet with " + people.QueryReplies.Length+ " replies");
            foreach (DirPeopleReplyPacket.QueryRepliesBlock block in people.QueryReplies)
            {
                Console.WriteLine("Status"+block.Online);
                if (block.Online)
                {
                    OnlineNotificationPacket inject = new OnlineNotificationPacket();
                    inject.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1];
                    inject.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock();
                    inject.AgentBlock[0].AgentID = block.AgentID;
                    loader.proxy.InjectPacket(inject, Direction.Incoming);
                }
                else
                {
                    OfflineNotificationPacket inject = new OfflineNotificationPacket();
                    inject.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1];
                    inject.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock();
                    inject.AgentBlock[0].AgentID = block.AgentID;
                    loader.proxy.InjectPacket(inject, Direction.Incoming);
                }
            }
            return packet;
        }
*/
        private Packet AvatarPropertiesReply(Packet packet, IPEndPoint sim)
        {
            // deconstruct the packet
            AvatarPropertiesReplyPacket properties = (AvatarPropertiesReplyPacket)packet;
            if ((properties.PropertiesData.Flags & AVATAR_ONLINE) != 0)
            {
                OnlineNotificationPacket inject = new OnlineNotificationPacket();
                inject.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[1];
                inject.AgentBlock[0] = new OnlineNotificationPacket.AgentBlockBlock();
                inject.AgentBlock[0].AgentID = properties.AgentData.AvatarID;
                loader.proxy.InjectPacket(inject, Direction.Incoming);
            }
            else
            {
                OfflineNotificationPacket inject = new OfflineNotificationPacket();
                inject.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[1];
                inject.AgentBlock[0] = new OfflineNotificationPacket.AgentBlockBlock();
                inject.AgentBlock[0].AgentID = properties.AgentData.AvatarID;
                loader.proxy.InjectPacket(inject, Direction.Incoming);
            }
            return packet;
        }
/*
        private Packet UUIDNameReply(Packet packet, IPEndPoint sim)
        {
            UUIDNameReplyPacket name = (UUIDNameReplyPacket)packet;
            foreach (UUIDNameReplyPacket.UUIDNameBlockBlock block in name.UUIDNameBlock)
            {
                if (friends.ContainsKey(block.ID))
                {
                    if (friends[block.ID].ToString() == "")
                    {
                        friends.Remove(block.ID);
                        string fullName = Helpers.FieldToUTF8String(block.FirstName) + " " + Helpers.FieldToUTF8String(block.LastName);
                        Console.WriteLine("Received name:" + fullName);
                        friends.Add(block.ID, fullName);
                        DirFindQueryPacket inject = new DirFindQueryPacket();
                        inject.AgentData.AgentID = loader.AgentID;
                        inject.AgentData.SessionID = loader.SessionID;
                        inject.QueryData.QueryFlags = 1;
                        inject.QueryData.QueryStart = 0;
                        inject.QueryData.QueryID = LLUUID.Random();
                        inject.QueryData.QueryText = Helpers.StringToField(fullName);
                        loader.proxy.InjectPacket(inject, Direction.Outgoing);
                    }
                }
            }
            return packet;
        }
*/
        private void fix_Click(object sender, EventArgs e)
        {
            try
            {
                /*if(friends == null)
                {
                    Console.WriteLine("Getting Friends List...");
                    IList buddy_list = (IList)loader.LoginInfo["buddy-list"];
                    friends=new Hashtable(buddy_list.Count);
                    for(int i=0; i<buddy_list.Count; i++)
                    {
                        LLUUID key=new LLUUID(((Hashtable)buddy_list[i])["buddy_id"].ToString());
                        friends.Add(key, loader.getName(key));
                    }
                    Console.WriteLine(buddy_list.Count + " friends loaded");
                }
                else
                {
                    foreach(LLUUID key in friends.Keys)
                    {
                        if(friends[key].ToString() != "")
                        {
                            Console.WriteLine("Checking " + friends[key].ToString());
                            DirFindQueryPacket inject=new DirFindQueryPacket();
                            inject.AgentData.AgentID=loader.AgentID;
                            inject.AgentData.SessionID=loader.SessionID;
                            inject.QueryData.QueryFlags=1;
                            inject.QueryData.QueryStart=0;
                            inject.QueryData.QueryID = LLUUID.Random();
                            inject.QueryData.QueryText = Helpers.StringToField(friends[key].ToString());
                            loader.proxy.InjectPacket(inject, Direction.Outgoing);
                        }
                        else
                        {
                            Console.WriteLine("Need name for " + key.ToString());
                            friends.Remove(key);
                            friends.Add(key, loader.getName(key));
                        }
                    }
                }*/

                IList buddy_list = (IList)loader.LoginInfo["buddy-list"];
                Console.WriteLine("buddies:" + buddy_list.Count);
                for (int i = 0; i < buddy_list.Count; i++)
                {
                    AvatarPropertiesRequestPacket inject = new AvatarPropertiesRequestPacket();
                    inject.AgentData.AgentID = loader.AgentID;
                    inject.AgentData.SessionID = loader.SessionID;
                    inject.AgentData.AvatarID = new LLUUID(((Hashtable)buddy_list[i])["buddy_id"].ToString());
                    loader.proxy.InjectPacket(inject, Direction.Outgoing);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }

        private void allon_Click(object sender, EventArgs e)
        {
            try
            {
                IList buddy_list = (IList)loader.LoginInfo["buddy-list"];
                Console.WriteLine("buddies:" + buddy_list.Count);
                OnlineNotificationPacket online = new OnlineNotificationPacket();
                online.AgentBlock = new OnlineNotificationPacket.AgentBlockBlock[buddy_list.Count];
                for (int i = 0; i < buddy_list.Count; i++)
                {
                    online.AgentBlock[i] = new OnlineNotificationPacket.AgentBlockBlock();
                    online.AgentBlock[i].AgentID = new LLUUID(((Hashtable)buddy_list[i])["buddy_id"].ToString());
                }
                loader.proxy.InjectPacket(online, Direction.Incoming);
            }
            catch(Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }

        private void alloff_Click(object sender, EventArgs e)
        {
            try
            {
                IList buddy_list = (IList)loader.LoginInfo["buddy-list"];
                Console.WriteLine("buddies:" + buddy_list.Count);
                OfflineNotificationPacket offline = new OfflineNotificationPacket();
                offline.AgentBlock = new OfflineNotificationPacket.AgentBlockBlock[buddy_list.Count];
                for (int i = 0; i < buddy_list.Count; i++)
                {
                    offline.AgentBlock[i] = new OfflineNotificationPacket.AgentBlockBlock();
                    offline.AgentBlock[i].AgentID = new LLUUID(((Hashtable)buddy_list[i])["buddy_id"].ToString());
                }
                loader.proxy.InjectPacket(offline, Direction.Incoming);
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                Console.WriteLine(ex.StackTrace);
            }
        }

        private void dump_Click(object sender, EventArgs e)
        {
            try
            {
                IList buddy_list = (IList)loader.LoginInfo["buddy-list"];
                StringBuilder str = new StringBuilder("You have " + buddy_list.Count+" buddies");
                str.AppendLine();
                for (int i = 0; i < buddy_list.Count; i++)
                {
                    LLUUID key=new LLUUID(((Hashtable)buddy_list[i])["buddy_id"].ToString());
                    str.AppendLine(key.ToStringHyphenated()+"     " + i + "     "+loader.getName(key));
                }
                friendsDump.Text = str.ToString();
            }
            catch (Exception ex)
            {
                friendsDump.Text = "Error, try logging in first";
            }
        }
    }
}